home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / ULARN.ARJ / ULARN.TAR / ularn / main.c < prev    next >
C/C++ Source or Header  |  1989-10-25  |  26KB  |  1,254 lines

  1. /*    main.c        */
  2. /* This game is bad for you. It is evil. It will rot your brain. */
  3. #include "header.h"
  4.  
  5. static char copyright[]=
  6. "\nUlarn was created by Phil Cordier and is based on Larn by Noah Morgan\n";
  7.  
  8. int srcount=0;    /* line counter for showstr()    */
  9. int dropflag=0; /* if 1 then don't lookforobject() next round */
  10. int rmst=80;    /* random monster creation counter        */
  11. int userid;    /* the players login user id number */
  12. int stayflag=0;
  13.  
  14. char     nowelcome=0,
  15. nomove=0; /* if (nomove) then don't count next iteration as a move */
  16.  
  17. static char viewflag=0;
  18. /*    if viewflag then we have done a 99 stay here and 
  19.     don't showcell in the main loop */
  20.  
  21. char restorflag=0;    /* 1 means restore has been done    */
  22. static char cmdhelp[] = "\
  23. Cmd line format: Ularn [-slicnh] [-o<optsfile>] [-##] [++]\n\
  24.   -s   show the scoreboard\n\
  25.   -i   show scoreboard with inventories\n\
  26.   -c   create new scoreboard (wizard only)\n\
  27.   -n   suppress welcome message on starting game\n\
  28.   -h   print this help text\n\
  29.   -o<optsfile>   specify .Ularnopts file to be used instead of \"~/.Ularnopts\"\n\
  30.   -##  specify level of difficulty (example: Ularn -5)\n\
  31.   -++  restore game checkpoint file\n";
  32.  
  33. /*
  34.     ************
  35.     MAIN PROGRAM
  36.     ************
  37.  */
  38.  
  39. main(argc,argv)
  40. int argc;
  41. char **argv;
  42. {
  43.     register int i;
  44.     int hard;
  45.     char *ptr=0;
  46.     struct passwd *pwe,*getpwuid();
  47.  
  48.     init_term();    /*setup the terminal (find out what type) for termcap */
  49.  
  50. /*
  51.  *    first task is to identify the player
  52.  */
  53.         if ((ptr = getlogin()) == NULL)
  54.           if (pwe=getpwuid(geteuid()))
  55.             ptr = pwe->pw_name;
  56.           else if ((ptr = getenv("USER")) == NULL) {
  57. noone:            fprintf(stderr, "Can't find your logname.  Who Are You?\n");
  58.             fflush(stderr);
  59.             exit(1);
  60.          }
  61.     if (ptr==NULL) goto noone;
  62.     if (strlen(ptr)==0) goto noone;
  63. /*
  64.  *    second task is to prepare the pathnames the player will need
  65.  */
  66.     strcpy(loginname,ptr); 
  67.  
  68.     /* save loginname of the user for logging purposes */
  69.     strcpy(logname,ptr);    
  70.  
  71.     /* this will be overwritten with the players name */
  72.     if ((ptr = getenv("HOME")) == NULL) 
  73.         if ((ptr = pwe->pw_dir) == NULL)
  74.             ptr = ".";
  75.  
  76.     /* save file name in home directory */
  77.     strcpy(savefilename, ptr);
  78.     strcat(savefilename, "/Ularn.sav");    
  79.  
  80.     sprintf(optsfile, "%s/.Ularnopts",ptr);    /* the .Ularnopts filename */
  81.     strcat(scorefile, SCORENAME);    /* the Ularn scoreboard filename */
  82.     strcat(logfile, LOGFNAME);
  83.  
  84.     /* Ularn activity logging filename */
  85.     strcat(helpfile, HELPNAME);    /* the Ularn on-line help file */
  86.     strcat(larnlevels, LEVELSNAME);    /* the pre-made cave level data file */
  87.     strcat(fortfile, FORTSNAME);    /* the fortune data file name */
  88. /*
  89.  *    now malloc the memory for the dungeon 
  90.  */
  91. cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY);
  92.  
  93.     if (cell == (struct cel *)NULL) 
  94.         died(-285);    /* malloc failure */
  95.  
  96.     if ( ( lpbuf = malloc ((5* BUFBIG)>>2) ) == (char *)NULL)
  97.         died(-285);
  98.  
  99.     if ( ( inbuffer = malloc( (5*MAXIBUF) >>2) ) == (char *)NULL)
  100.         died(-285);
  101.  
  102.     lcreat((char*)0);    
  103.     newgame();        /*    set the initial clock  */ 
  104.     hard= -1;
  105.  
  106. /*
  107.  *    now make scoreboard if it is not there (don't clear) 
  108.  */
  109.     if (access(scorefile,0) == -1) /* not there */
  110.         makeboard();
  111.  
  112. /*
  113.  *    now process the command line arguments 
  114.  */
  115.     for (i=1; i<argc; i++) {
  116.         if (argv[i][0] == '-')
  117.           switch(argv[i][1]) {
  118.             case 's': showscores();  
  119.                   exit(0);  /* show scoreboard   */
  120.  
  121.             case 'i': showallscores();  
  122.                   exit(0);  /* show all scoreboard */
  123.  
  124.             case 'c': /*anyone with password can create scoreboard*/
  125.             setupvt100();    
  126.             lprcat("Preparing to initialize the scoreboard.\n");
  127.                   if (getpassword() != 0) {
  128.                     makeboard(); 
  129.                     showscores();
  130.                   }
  131.                   exit(0);
  132.  
  133.             case 'n':    nowelcome=1; 
  134.                     argv[i][0]=0; 
  135.                     break;
  136.  
  137.             case '0': case '1': case '2': case '3': 
  138.             case '4': case '5': case '6': case '7': 
  139.             case '8': case '9':    /* for hardness */
  140.                     sscanf(&argv[i][1],"%d",&hard);    
  141.                     if (hard > 100) hard = 100;
  142.                     break;
  143.  
  144.             case 'h':    /* print out command line arguments */
  145.                     fprintf(stderr, "%s", cmdhelp);
  146.                     fflush(stderr);
  147.                     exit(0);
  148.             case 'o':    /* specify a .Ularnopts filename */
  149.                     strncpy(optsfile,argv[i]+2,127);  break;
  150.             default:
  151.                 fprintf(stderr,"Unknown option <%s>\n",argv[i]);
  152.                 fprintf(stderr,"%s", cmdhelp);  
  153.                 fflush(stderr);
  154.                 exit(1);
  155.             };
  156.         if (argv[i][0] == '+') {
  157.             clear();    restorflag = 1;
  158.             if (argv[i][1] == '+') {
  159.                 hitflag=1; 
  160.                 restoregame(ckpfile); 
  161.                 /* restore checkpointed game */
  162.             }
  163.             i = argc;
  164.         }
  165.     }
  166.  
  167.  
  168.     userid = geteuid();    /* obtain the user's effective id number */
  169.  
  170.     sigsetup();    /* trap all needed signals    */
  171.     sethard(hard);    /* set up the desired difficulty    */
  172.     setupvt100();    /* setup the terminal special mode    */
  173.     readopts();    /* read the options file if there is one */
  174.  
  175.     /* restore game if need to */
  176.     if (access(savefilename,0)==0)    {
  177.         clear();    
  178.         restorflag = 1;
  179.         hitflag=1;    
  180.         restoregame(savefilename);  
  181.     }
  182.  
  183.     /* create new game */
  184.     if (c[HP]==0) {
  185.         makeplayer();    /*    make the character that will play*/
  186.         newcavelevel(0);/*    make the dungeon */
  187.         predostuff = 1;    
  188.  
  189.         /* tell signals that we are in the welcome screen */
  190.         if (nowelcome==0) 
  191.             welcome();     /* welcome the player to the game */
  192.     }
  193.  
  194.     drawscreen();    /*    show the initial dungeon */
  195.  
  196.     /* tell the trap functions that they must do a showplayer()
  197.        from here on */
  198.     predostuff = 2;    
  199.  
  200.     yrepcount = hit2flag = 0;
  201.     /*
  202.      *    M A I N  L O O P
  203.      */
  204.     while (1) {
  205.         if (dropflag==0) 
  206.             lookforobject(); /* see if there is an object here*/
  207.         else 
  208.             dropflag=0; /* don't show it just dropped an item */
  209.  
  210.         if (hitflag==0) {     
  211.             if (c[HASTEMONST]) 
  212.                 movemonst(); 
  213.             movemonst(); 
  214.         }    /* move the monsters    */
  215.  
  216.         if (viewflag==0) 
  217.             showcell(playerx,playery); 
  218.         else viewflag=0;    /* show stuff around player */
  219.  
  220.         if (hit3flag) 
  221.             flushall();
  222.         hitflag = hit3flag = 0;    
  223.         nomove=1;
  224.         bot_linex();    /* update bottom line */
  225.  
  226.         while (nomove)/*    get commands and make moves    */
  227.         {
  228.             if (hit3flag) 
  229.                 flushall();
  230.             nomove=0; 
  231.             parse();
  232.         }    
  233.  
  234.         regen();    /*    regenerate hp and spells*/
  235.  
  236.         if (c[TIMESTOP]==0)
  237.           if (--rmst <= 0) {     
  238.             rmst = 120-(level<<2); 
  239.             fillmonst(makemonst(level)); 
  240.           }
  241.     }    /* end main loop */
  242. }    /* end main */
  243.  
  244. /*
  245.     showstr()
  246.  
  247.     show character's inventory
  248.  */
  249. showstr()
  250. {
  251.     register int i,number;
  252.  
  253.     for (number=3, i=0; i<26; i++)
  254.         if (iven[i]) number++;    /* count items in inventory */
  255.     t_setup(number);    
  256.     qshowstr();
  257.     t_endup(number);
  258. }
  259.  
  260. qshowstr()
  261. {
  262.     register int k,sigsav;
  263.  
  264.     srcount=0;  
  265.     sigsav=nosignal;  
  266.     nosignal=1; /* don't allow ^c etc */
  267.     if (c[GOLD]) {     
  268.         lprintf(".)   %d gold pieces",(long)c[GOLD]); 
  269.         srcount++; 
  270.     }
  271.  
  272.     for (k=0; k<=26; k++)
  273.         if (iven[k]) show3(k);
  274.  
  275.     lprintf("\nElapsed time is %d.  You have %d mobuls left",
  276.         (long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100));
  277.     more();        
  278.     nosignal=sigsav;
  279. }
  280.  
  281. /*
  282.  *    subroutine to clear screen depending on # lines to display
  283.  */
  284. t_setup(count)
  285. register int count;
  286. {
  287.     if (count<20)  {
  288.         cl_up(79,count);  
  289.         cursor(1,1);
  290.     }
  291.     else {
  292.         resetscroll(); 
  293.         clear();
  294.     }
  295. }
  296.  
  297. /*
  298.  *    subroutine to restore normal display screen depending on t_setup()
  299.  */
  300. t_endup(count)
  301. register int count;
  302. {
  303.     if (count<18)  /* how did we clear the screen? */
  304.         draws(0,MAXX,0,(count>MAXY) ? MAXY : count);
  305.     else {
  306.         drawscreen(); 
  307.         setscroll();
  308.     }
  309. }
  310.  
  311. /*
  312.     function to show the things player is wearing only
  313.  */
  314. showwear()
  315. {
  316.     register int i,j,sigsav,count;
  317.  
  318.     sigsav=nosignal;  
  319.     nosignal=1; /* don't allow ^c etc */
  320.     srcount=0;
  321.  
  322.     /* count number of items we will display */
  323.     for (count=2,j=0; j<=26; j++)     
  324.        if (i=iven[j])
  325.         switch(i) {
  326.             case OLEATHER:    
  327.             case OPLATE:    
  328.             case OCHAIN:
  329.             case ORING:        
  330.             case OSTUDLEATHER:    
  331.             case OSPLINT:
  332.             case OPLATEARMOR:    
  333.             case OSSPLATE:    
  334.             case OSHIELD:
  335.             case OELVENCHAIN:
  336.                 count++;
  337.         };
  338.  
  339.     t_setup(count);
  340.  
  341.     for (i=22; i<93; i++)
  342.          for (j=0; j<=26; j++)
  343.            if (i==iven[j])
  344.             switch(i) {
  345.                 case OLEATHER:    
  346.                 case OPLATE:    
  347.                 case OCHAIN:
  348.                 case ORING:        
  349.                 case OSTUDLEATHER:    
  350.                 case OSPLINT:
  351.                 case OPLATEARMOR:    
  352.                 case OSSPLATE:    
  353.                 case OSHIELD:
  354.                 case OELVENCHAIN:
  355.                     show3(j);
  356.             };
  357.     more();        
  358.     nosignal=sigsav;    
  359.     t_endup(count);
  360. }
  361.  
  362. /*
  363.     function to show the things player can wield only 
  364.  */
  365. showwield()
  366. {
  367.     register int i,j,sigsav,count;
  368.     sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  369.     srcount=0;
  370.  
  371.      for (count=2,j=0; j<=26; j++)    /* count how many items */
  372.        if (i=iven[j])
  373.         switch(i) {
  374.             case ODIAMOND:  case ORUBY:  case OEMERALD:  
  375.             case OSAPPHIRE:
  376.             case OBOOK:     case OCHEST:  case OLARNEYE: 
  377.             case ONOTHEFT:
  378.             case OSPIRITSCARAB:  case OCUBEofUNDEAD:
  379.             case OPOTION:   
  380.             case OORB:
  381.             case OHANDofFEAR:
  382.             case OBRASSLAMP:
  383.             case OURN:
  384.             case OWWAND:
  385.             case OSPHTALISMAN:
  386.             case OSCROLL:  break;
  387.             default:  count++;
  388.         };
  389.  
  390.     t_setup(count);
  391.  
  392.     for (i=22; i<93; i++)
  393.          for (j=0; j<=26; j++)
  394.            if (i==iven[j])
  395.             switch(i) {
  396.                 case ODIAMOND:  case ORUBY:  
  397.                 case OEMERALD:  case OSAPPHIRE:
  398.                 case OBOOK:     case OCHEST:  
  399.                 case OLARNEYE: case ONOTHEFT:
  400.                 case OSPIRITSCARAB:  case OCUBEofUNDEAD:
  401.                 case OPOTION:   case OHANDofFEAR:
  402.                 case OBRASSLAMP:  case OURN:
  403.                 case OSPHTALISMAN:
  404.                 case OWWAND:
  405.                 case OORB: case OSCROLL:  break;
  406.                 default:  show3(j);
  407.             };
  408.         more();        
  409.         nosignal=sigsav;    
  410.         t_endup(count);
  411.     }
  412.  
  413. /*
  414.  *    function to show the things player can read only
  415.  */
  416. showread()
  417.     {
  418.     register int i,j,sigsav,count;
  419.     sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  420.     srcount=0;
  421.  
  422.     for (count=2,j=0; j<=26; j++)
  423.         switch(iven[j]) {
  424.             case OBOOK:    
  425.             case OSCROLL:    
  426.                 count++;
  427.             };
  428.     t_setup(count);
  429.  
  430.     for (i=22; i<84; i++)
  431.          for (j=0; j<=26; j++)
  432.            if (i==iven[j])
  433.             switch(i) {
  434.                 case OBOOK:    
  435.                 case OSCROLL:    
  436.                     show3(j);
  437.             };
  438.         more();    
  439.         nosignal=sigsav;    
  440.         t_endup(count);
  441.     }
  442.  
  443. /*
  444.  *    function to show the things player can eat only
  445.  */
  446. showeat()
  447. {
  448.     register int i,j,sigsav,count;
  449.  
  450.     sigsav=nosignal;  
  451.     nosignal=1; /* don't allow ^c etc */
  452.     srcount=0;
  453.  
  454.     for (count=2,j=0; j<=26; j++)
  455.         switch(iven[j]) {
  456.             case OCOOKIE:    
  457.                 count++;
  458.         };
  459.     t_setup(count);
  460.  
  461.     for (i=22; i<84; i++)
  462.          for (j=0; j<=26; j++)
  463.            if (i==iven[j])
  464.             switch(i) {
  465.                 case OCOOKIE:    
  466.                     show3(j);
  467.             };
  468.         more();        
  469.         nosignal=sigsav;    
  470.         t_endup(count);
  471.     }
  472.  
  473. /*
  474.     function to show the things player can quaff only
  475.  */
  476. showquaff()
  477. {
  478.     register int i,j,sigsav,count;
  479.  
  480.     sigsav=nosignal;  
  481.     nosignal=1; /* don't allow ^c etc */
  482.     srcount=0;
  483.  
  484.     for (count=2,j=0; j<=26; j++)
  485.         switch(iven[j]) {
  486.             case OPOTION:    
  487.                 count++;
  488.         };
  489.     t_setup(count);
  490.  
  491.     for (i=22; i<84; i++)
  492.       for (j=0; j<=26; j++)
  493.          if (i==iven[j])
  494.         switch(i) {
  495.             case OPOTION:    
  496.                 show3(j);
  497.             };
  498.     more();            
  499.     nosignal=sigsav;        
  500.     t_endup(count);
  501. }
  502.  
  503. show1(idx,str2)
  504. register int idx;
  505. register char *str2[];
  506. {
  507.     if (str2==0)  
  508.         lprintf("\n%c)   %s",idx+'a',objectname[iven[idx]]);
  509.     else if (*str2[ivenarg[idx]]==0)  
  510.         lprintf("\n%c)   %s",idx+'a',objectname[iven[idx]]);
  511.     else 
  512.         lprintf("\n%c)   %s of%s",
  513.             idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]);
  514. }
  515.  
  516. show3(index)
  517. register int index;
  518. {
  519.     switch(iven[index]) {
  520.         case OPOTION:    show1(index,potionname);  break;
  521.         case OSCROLL:    show1(index,scrollname);  break;
  522.         case OLARNEYE:        
  523.         case OBOOK:            
  524.         case OSPIRITSCARAB:
  525.         case ODIAMOND:        
  526.         case ORUBY:            
  527.         case OCUBEofUNDEAD:
  528.         case OEMERALD:        
  529.         case OCHEST:        
  530.         case OCOOKIE:
  531.         case OSAPPHIRE:        
  532.         case OORB:    
  533.         case OHANDofFEAR:
  534.         case OBRASSLAMP:
  535.         case OURN:
  536.         case OWWAND:
  537.         case OSPHTALISMAN:
  538.         case ONOTHEFT:        show1(index,(char **)0);  break;
  539.  
  540.         default:    
  541.             lprintf("\n%c)   %s",index+'a',objectname[iven[index]]);
  542.             if (ivenarg[index]>0) 
  543.                 lprintf(" + %d",(long)ivenarg[index]);
  544.             else if (ivenarg[index]<0) 
  545.                 lprintf(" %d",(long)ivenarg[index]);
  546.             break;
  547.     }
  548.     if (c[WIELD]==index) 
  549.         lprcat(" (weapon in hand)");
  550.     if ((c[WEAR]==index) || (c[SHIELD]==index))  
  551.         lprcat(" (being worn)");
  552.     if (++srcount>=22) { 
  553.         srcount=0; 
  554.         more(); 
  555.         clear(); 
  556.     }
  557. }
  558.  
  559. /*
  560.     subroutine to randomly create monsters if needed
  561.  */
  562. randmonst()
  563. {    /*    don't make monsters if time is stopped    */
  564.     if (c[TIMESTOP]) return;    
  565.     if (--rmst <= 0) {
  566.         rmst = 120 - (level<<2);  
  567.         fillmonst(makemonst(level));
  568.     }
  569. }
  570.  
  571.  
  572. /*
  573.     parse()
  574.  
  575.     get and execute a command
  576.  */
  577. parse()
  578. {
  579.     register int i,j,k,flag;
  580.     while    (1) {
  581.         k = yylex();
  582.         /* get the token from the input and switch on it    */
  583.         switch(k)    {
  584.             case 'A':    if (wizard) 
  585.                         diag(); 
  586.                     yrepcount=0;
  587.                     return;
  588.             case 'h':    moveplayer(4);    
  589.                     return;    /* west    */
  590.             case 'H':    run(4);
  591.                     return;    /* west    */
  592.             case 'l':    moveplayer(2);    
  593.                     return;    /* east    */
  594.             case 'L':    run(2);        
  595.                     return;    /* east    */
  596.             case 'j':    moveplayer(1);    
  597.                     return;    /* south */
  598.             case 'J':    run(1);            
  599.                     return;    /* south */
  600.             case 'k':    moveplayer(3);    
  601.                     return;    /* north */
  602.             case 'K':    run(3);            
  603.                     return;    /* north */
  604.             case 'u':    moveplayer(5);    
  605.                     return;    /* northeast */
  606.             case 'U':    run(5);            
  607.                     return;    /* northeast */
  608.             case 'y':    moveplayer(6);  
  609.                     return;    /* northwest */
  610.             case 'Y':    run(6);            
  611.                     return;    /* northwest */
  612.             case 'n':    moveplayer(7);    
  613.                     return;    /* southeast */
  614.             case 'N':    run(7);            
  615.                     return;    /* southeast */
  616.             case 'b':    moveplayer(8);    
  617.                     return;    /* southwest */
  618.             case 'B':    run(8);            
  619.                     return;    /* southwest */
  620.  
  621.             case '.':    if (yrepcount) 
  622.                         viewflag=1; 
  623.                     return;    /* stay here */
  624.  
  625.             case 'w':    yrepcount=0;    
  626.                     wield();    
  627.                     return;    /* wield a weapon */
  628.  
  629.             case 'W':    yrepcount=0;    
  630.                     wear();        
  631.                     return;    /* wear armor    */
  632.  
  633.             case 'r':    yrepcount=0;
  634.                     if (c[BLINDCOUNT]) { 
  635.                         cursors(); 
  636.                         lprcat("\nYou can't read anything when you're blind!"); 
  637.                     } else if (c[TIMESTOP]==0) 
  638.                         readscr(); 
  639.                     return;    /* to read a scroll */
  640.  
  641.             case 'q':    yrepcount=0;    
  642.                     if (c[TIMESTOP]==0) 
  643.                         quaff();    
  644.                     return;    /* quaff a potion */
  645.  
  646.             case 'd':    yrepcount=0;    
  647.                     if (c[TIMESTOP]==0) 
  648.                     dropobj(); 
  649.                     return;    /* to drop an object */
  650.  
  651.             case 'c':    yrepcount=0;    
  652.                     cast();        
  653.                     return;    /* cast a spell    */
  654.  
  655.             case 'i':    yrepcount=0;    
  656.                     nomove=1;  
  657.                     showstr();    
  658.                     return;    /* status */
  659.  
  660.             case 'e':    yrepcount=0;
  661.                     if (c[TIMESTOP]==0) 
  662.                         eatcookie(); 
  663.                     return;    /* to eat a fortune cookie */
  664.  
  665.             case 'D':    yrepcount=0;    
  666.                     seemagic(0);    
  667.                     nomove=1; 
  668.                     return;    /*list spells and scrolls */
  669.  
  670.             case '?':    yrepcount=0;    
  671.                     help(); 
  672.                     nomove=1; 
  673.                     return;    /*give the help screen*/
  674.  
  675.             case 'S':    clear();  
  676.                     lprcat("Saving . . ."); 
  677.                     lflush();  
  678.                     savegame(savefilename); 
  679.                     wizard=1; 
  680.                     died(-257);
  681.                     /* save the game - 
  682.                        doesn't return */
  683.  
  684.             case 'Z':    yrepcount=0;    
  685.                 if (wizard) {
  686.                     int t;
  687.                     cursors();
  688.             lprcat("\nWhich level do you wish to teleport to? ");
  689.                     t = readnum(20);
  690.                     if (t > 20 || t < 0) {
  691.                         lprcat(" sorry!");
  692.                         return;
  693.                     }
  694.                     playerx = rnd(MAXX-2);    
  695.                     playery = rnd(MAXY-2);
  696.                     newcavelevel(t);  
  697.                     positionplayer();
  698.                     draws(0,MAXX,0,MAXY); 
  699.                     bot_linex();
  700.                     return;
  701.                 }
  702.                     if (c[LEVEL]>9) { 
  703.                         oteleport(1); 
  704.                         return; 
  705.                     }
  706.                     cursors();
  707.                 lprcat("\nYou don't know how to teleport yet");
  708.                     return;    /* teleport yourself    */
  709.  
  710.             case '^':    /* identify traps */  
  711.                     flag=yrepcount=0;  
  712.                     cursors();
  713.                     lprc('\n');  
  714.                     for (j=playery-1; j<playery+2; j++) {
  715.                       if (j < 0) j=0;        
  716.                       if (j >= MAXY) break;
  717.                       for (i=playerx-1; i<playerx+2; i++) {
  718.                         if (i < 0) i=0;    
  719.                         if (i >= MAXX) break;
  720.                         switch(item[i][j]) {
  721.                         case OTRAPDOOR:        
  722.                         case ODARTRAP:
  723.                         case OTRAPARROW:
  724.                         case OTELEPORTER:
  725.                         case OELEVATORUP:
  726.                         case OELEVATORDOWN:
  727.                          lprcat("\nIt's "); 
  728.                          lprcat(objectname[item[i][j]]);
  729.                         flag++;
  730.                         };
  731.                     }
  732.                       }
  733.                       if (flag==0) 
  734.                     lprcat("\nNo traps are visible");
  735.                       return;
  736.  
  737.             case '#':    
  738.                 yrepcount=0;    
  739.                 cursors(); 
  740.                 nomove=1;
  741.                 if (getpassword()==0) {
  742.                     scbr(); 
  743.                     return;
  744.                 }
  745.                 scbr();
  746.                 raiseexperience(370 * 1000000);
  747.                 bottomline();
  748.                 drawscreen();
  749.                 return;
  750.  
  751. #if WIZID
  752.             case '_': /*this is the fudge player password 
  753.                     for wizard mode*/
  754.                 yrepcount=0;    
  755.                 cursors(); 
  756.                 nomove=1;
  757.                 if (getpassword()==0) {
  758.                     scbr(); 
  759.                     return;
  760.                 }
  761.                 wizard=1;  
  762.                 scbr(); 
  763.                 for (i=0; i<6; i++)  
  764.                     c[i]=70;  
  765.                 iven[0]=iven[1]=0;
  766.                 take(OPROTRING,50);   
  767.                 take(OLANCE,25);  
  768.                 for (i=0; i<26; i++)
  769.                   if (iven[i]==OLANCE && ivenarg[i]==25) {
  770.                         c[WIELD]=i;
  771.                         break;
  772.                     }
  773.                 c[LANCEDEATH]=1;   
  774.                 c[WEAR] = c[SHIELD] = -1;
  775.                 raiseexperience(370*1000000); 
  776.                 c[AWARENESS] += 25000;
  777.                 {
  778.                     register int i,j;
  779.                     for (i=0; i<MAXY; i++)
  780.                       for (j=0; j<MAXX; j++)  
  781.                         know[j][i]=1;
  782.                     for (i=0; i<SPNUM; i++)    
  783.                         spelknow[i]=1;
  784.                     for (i=0; i<MAXSCROLL; i++)  
  785.                         scrollname[i][0]=' ';
  786.                     for (i=0; i<MAXPOTION; i++)  
  787.                         potionname[i][0]=' ';
  788.                 }
  789.                 for (i=0; i<MAXSCROLL; i++)
  790.                   if (strlen(scrollname[i])>2) 
  791.                   {     item[i][0]=OSCROLL; 
  792.                     iarg[i][0]=i; 
  793.                   }
  794.                 for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
  795.                   if (strlen(potionname[i-MAXX+MAXPOTION])>2) 
  796.                     /* no null items */
  797.                   {     item[i][0]=OPOTION; 
  798.                     iarg[i][0]=i-MAXX+MAXPOTION; 
  799.                   }
  800.                 for (i=1; i<MAXY; i++)
  801.                 {     item[0][i]=i; 
  802.                     iarg[0][i]=0; 
  803.                 }
  804.                 for (i=MAXY; i<MAXY+MAXX; i++)
  805.                 {     item[i-MAXY][MAXY-1]=i; 
  806.                     iarg[i-MAXY][MAXY-1]=0; 
  807.                 }
  808.                 for (i=MAXX+MAXY; i<MAXX+MAXY+MAXY; i++)
  809.                 {     item[MAXX-1][i-MAXX-MAXY]=i; 
  810.                     iarg[MAXX-1][i-MAXX-MAXY]=0; 
  811.                 }
  812.                 c[GOLD]+=250000;
  813.                 bottomline();
  814.                 drawscreen();    
  815.                 return;
  816. #endif /* WIZID */
  817.  
  818.             case 'T':    yrepcount=0;    
  819.                     cursors();  
  820.                     if (c[SHIELD] != -1) { 
  821.                         c[SHIELD] = -1; 
  822.                         lprcat("\nYour shield is off");
  823.                          bottomline(); 
  824.                     } else
  825.                     if (c[WEAR] != -1) { 
  826.                         c[WEAR] = -1; 
  827.                         lprcat("\nYour armor is off"); 
  828.                         bottomline(); 
  829.                     }
  830.                 else lprcat("\nYou aren't wearing anything");
  831.                     return;
  832.  
  833.             case 'g':    cursors();
  834.     lprintf("\nThe stuff you are carrying presently weighs %d pounds",
  835.         (long)packweight());
  836.  
  837.             case ' ':    yrepcount=0;    
  838.                     nomove=1;  
  839.                     return;
  840.  
  841.             case 'v':    yrepcount=0;    
  842.                     cursors();
  843. lprintf( "\nThe Addiction of Ularn, by Satyr. Difficulty : %d",
  844.     (long)c[HARDGAME]);
  845.                     if (wizard) lprcat(" (WIZARD)");
  846.                     nomove=1;
  847.                     if (cheat) lprcat(" (Cheater)");
  848.                         lprcat(copyright); 
  849.                     return;
  850.  
  851.             case 'Q':    yrepcount=0;
  852.                     quit(); 
  853.                     nomove=1;    
  854.                     return;    /* quit    */
  855.  
  856.             case 'L'-64:      yrepcount=0;    
  857.                     drawscreen();  
  858.                     nomove=1; 
  859.                     return;    /*    look        */
  860.  
  861.             case 'P':    cursors(); 
  862.                     if (outstanding_taxes>0)
  863.                     lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes);
  864.                     else
  865.                         lprcat("\nYou do not owe any taxes.");
  866.                     return;
  867.         };
  868.     }
  869. }
  870.  
  871. parse2()
  872. {
  873.     if (c[HASTEMONST]) 
  874.         movemonst(); 
  875.     movemonst(); /*    move the monsters */
  876.     randmonst();    
  877.     regen();
  878. }
  879.  
  880. run(dir)
  881. int dir;
  882. {
  883.     register int i;
  884.     i=1; 
  885.     while (i) {
  886.         i=moveplayer(dir);
  887.         if (i>0) {      
  888.             if (c[HASTEMONST]) 
  889.                 movemonst();  
  890.             movemonst(); 
  891.             randmonst(); 
  892.             regen(); 
  893.         }
  894.         if (hitflag) i=0;
  895.         if (i!=0)  
  896.             showcell(playerx,playery);
  897.     }
  898. }
  899.  
  900. /*
  901.     function to wield a weapon
  902.  */
  903. wield()    
  904. {
  905.     register int i;
  906.  
  907.     while (1) {
  908.         if ((i = whatitem("wield"))=='\33')  return;
  909.         if (i != '.') {
  910.             if (i=='*') showwield();
  911.             else  if (iven[i-'a']==0) { ydhi(i); return; }
  912.             else if (iven[i-'a']==OPOTION) { ycwi(i); return; }
  913.             else if (iven[i-'a']==OSCROLL) { ycwi(i); return; }
  914.             else  if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD)) {
  915.                   lprcat("\nBut one arm is busy with your shield!");
  916.                 return; 
  917.             }
  918.             else  {
  919.                 c[WIELD]=i-'a'; 
  920.                 if (iven[i-'a'] == OLANCE) c[LANCEDEATH]=1; 
  921.                 else c[LANCEDEATH]=0;  
  922.                 bottomline(); 
  923.                 return; 
  924.             }
  925.         }
  926.     }
  927. }
  928.  
  929. /*
  930.     common routine to say you don't have an item
  931.  */
  932. ydhi(x)
  933. int x;
  934. { cursors();  lprintf("\nYou don't have item %c!",x); }
  935.  
  936. ycwi(x)
  937. int x;
  938. { cursors();  lprintf("\nYou can't wield item %c!",x); }
  939.  
  940. /*
  941.     function to wear armor
  942.  */
  943. wear()
  944. {
  945.     register int i;
  946.     while (1) {
  947.         if ((i = whatitem("wear"))=='\33')  return;
  948.         if (i != '.') {
  949.             if (i=='*') showwear(); else
  950.             switch(iven[i-'a']) {
  951.                 case 0:  ydhi(i); return;
  952.                 case OLEATHER:  
  953.                 case OCHAIN:  
  954.                 case OPLATE:    
  955.                 case OSTUDLEATHER:
  956.                 case ORING:        
  957.                 case OSPLINT:    
  958.                 case OPLATEARMOR:    
  959.                 case OELVENCHAIN:
  960.                 case OSSPLATE:
  961.                   if (c[WEAR] != -1) { 
  962.                   lprcat("\nYou're already wearing some armor");
  963.                     return; }
  964.                   c[WEAR]=i-'a';  
  965.                   bottomline(); 
  966.                   return;
  967.  
  968.                 case OSHIELD:    
  969.                   if (c[SHIELD] != -1) { 
  970.                    lprcat("\nYou are already wearing a shield");
  971.                     return; 
  972.                   }
  973.                   if (iven[c[WIELD]]==O2SWORD) {
  974.              lprcat("\nYour hands are busy with the two handed sword!");
  975.                     return; 
  976.                 }
  977.                   c[SHIELD] = i-'a';  bottomline(); return;
  978.  
  979.                 default: lprcat("\nYou can't wear that!");
  980.             };
  981.         }
  982.     }
  983. }
  984.  
  985. /*
  986.     function to drop an object
  987.  */
  988. dropobj()
  989. {
  990.     register int i;
  991.     register char *p;
  992.     long amt;
  993.  
  994.     p = &item[playerx][playery];
  995.     while (1) {
  996.         if ((i = whatitem("drop"))=='\33')  return;
  997.         if (i=='*') 
  998.             showstr(); 
  999.         else {
  1000.             /* drop some gold */
  1001.             if (i=='.')    {
  1002.                 if (*p) { 
  1003.                 lprcat("\nThere's something here already!"); 
  1004.                     return; 
  1005.                 }
  1006.                 lprcat("\n\n");
  1007.                 cl_dn(1,23);
  1008.                 lprcat("How much gold do you drop? ");
  1009.                 if ((amt=readnum((long)c[GOLD])) == 0) return;
  1010.                 if (amt>c[GOLD]) { 
  1011.                     lprcat("\nYou don't have that much!"); 
  1012.                     return; 
  1013.                 }
  1014.                 if (amt<=32767) { 
  1015.                     *p=OGOLDPILE; 
  1016.                     i=amt; 
  1017.                 }
  1018.                 else if (amt<=327670L) { 
  1019.                     *p=ODGOLD; 
  1020.                     i=amt/10; 
  1021.                     amt = 10*i; 
  1022.                 }
  1023.                 else if (amt<=3276700L) { 
  1024.                     *p=OMAXGOLD; 
  1025.                     i=amt/100; 
  1026.                     amt = 100*i; 
  1027.                 }
  1028.                 else if (amt<=32767000L) { 
  1029.                     *p=OKGOLD; 
  1030.                     i=amt/1000; 
  1031.                     amt = 1000*i; 
  1032.                 }
  1033.                 else { 
  1034.                     *p=OKGOLD; 
  1035.                     i=32767; 
  1036.                     amt = 32767000L; 
  1037.                 }
  1038.                 c[GOLD] -= amt; 
  1039.                 lprintf("You drop %d gold pieces",(long)amt);
  1040.                 iarg[playerx][playery]=i; 
  1041.                 bottomgold();
  1042.                 know[playerx][playery]=0; 
  1043.                 dropflag=1;  
  1044.                 return;
  1045.             }
  1046.             drop_object(i-'a');
  1047.             return;
  1048.         }
  1049.     }
  1050. }
  1051.  
  1052. /*
  1053.  *    readscr()        Subroutine to read a scroll one is carrying
  1054.  */
  1055. readscr()
  1056.     {
  1057.     register int i;
  1058.     while (1) {
  1059.         if ((i = whatitem("read"))=='\33')  return;
  1060.         if (i != '.') {
  1061.             if (i=='*') showread(); else {
  1062.                 if (iven[i-'a']==OSCROLL) { read_scroll(ivenarg[i-'a']); iven[i-'a']=0; return; }
  1063.                 if (iven[i-'a']==OBOOK)   { readbook(ivenarg[i-'a']);  iven[i-'a']=0; return; }
  1064.                 if (iven[i-'a']==0) { ydhi(i); return; }
  1065.                 lprcat("\nThere's nothing on it to read");  return;
  1066.                 }
  1067.             }
  1068.         }
  1069.     }
  1070.  
  1071. /*
  1072.  *    subroutine to eat a cookie one is carrying
  1073.  */
  1074. eatcookie()
  1075. {
  1076.     register int i;
  1077.     char *p;
  1078.  
  1079.     while (1) {
  1080.     if ((i = whatitem("eat"))=='\33')  
  1081.         return;
  1082.     if (i != '.')
  1083.         if (i=='*') showeat(); else {
  1084.             if (iven[i-'a']==OCOOKIE) {
  1085.                 lprcat("\nThe cookie was delicious.");
  1086.                 iven[i-'a']=0;
  1087.                 if (!c[BLINDCOUNT]) {
  1088.                     if (p=fortune(fortfile)) {
  1089.                         lprcat("  Inside you find a scrap of paper that says:\n");
  1090.                         lprcat(p);
  1091.                         }
  1092.                     }
  1093.                 return;
  1094.                 }
  1095.             if (iven[i-'a']==0) { ydhi(i); return; }
  1096.             lprcat("\nYou can't eat that!");  return;
  1097.         }
  1098.     }
  1099. }
  1100.  
  1101. /*
  1102.  *    subroutine to quaff a potion one is carrying
  1103.  */
  1104. quaff()
  1105. {
  1106.     register int i;
  1107.  
  1108.     while (1) {
  1109.         if ((i = qwhatitem())=='\33')  return;
  1110.         if (i != '.') {
  1111.             if (i=='*') showquaff(); 
  1112.             else {
  1113.                 if (iven[i-'a']==OPOTION) { 
  1114.                     quaffpotion(ivenarg[i-'a']); 
  1115.                     iven[i-'a']=0; 
  1116.                     return; 
  1117.                 }
  1118.                 if (iven[i-'a']==0) { ydhi(i); return; }
  1119.         lprcat("\nYou wouldn't want to quaff that, would you? ");  
  1120.                 return;
  1121.             }
  1122.         }
  1123.     }
  1124. }
  1125.  
  1126. qwhatitem()
  1127. {
  1128.     int j, i=0;
  1129.     char gack[26];
  1130.  
  1131.     cursors();
  1132.     for (j=0; j<=26; j++)
  1133.         switch(iven[j]) {
  1134.             case OPOTION:    gack[i++] = j;
  1135.         };
  1136.     lprintf("\nWhat do you want to quaff [");
  1137.     if (i)
  1138.         for (j=0;j<i;j++) 
  1139.             lprintf("%c",gack[j] + 'a');
  1140.     lprintf(" * for all] ?");
  1141.     i=0; 
  1142.     while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) 
  1143.         i=getcharacter();
  1144.     if (i=='\33')  
  1145.         lprcat(" aborted");
  1146.     return(i);
  1147. }
  1148.  
  1149. /*
  1150.     function to ask what player wants to do
  1151.  */
  1152. whatitem(str)
  1153. char *str;
  1154. {
  1155.     register int j=0, flag=0, i=0;
  1156.     int wld=0, q=0, r=0, w=0, e=0, d=0;
  1157.     char gack[26];
  1158.  
  1159.     cursors();
  1160.     if (!strcmp(str, "wield")) wld = 1;
  1161.     else if (!strcmp(str, "quaff")) q = 1;
  1162.      else if (!strcmp(str, "read")) r = 1;
  1163.     else if (!strcmp(str, "wear")) w = 1;
  1164.     else if (!strcmp(str, "eat")) e = 1;
  1165.     else if (!strcmp(str, "drop")) d = 1;
  1166.  
  1167.     for (j=0; j<=26; j++) {
  1168.         switch(iven[j]) {
  1169.         case OSWORDofSLASHING :
  1170.         case OHAMMER:
  1171.         case OSWORD:
  1172.         case O2SWORD:
  1173.         case OSPEAR :
  1174.         case ODAGGER:
  1175.         case OBATTLEAXE:
  1176.         case OLONGSWORD:
  1177.         case OFLAIL:
  1178.         case OSLAYER :
  1179.         case OLANCE :
  1180.                 flag = 1; break; /* wield */
  1181.         case OPOTION:    
  1182.                 flag = 2; break; /* quaff */
  1183.         case OSCROLL:
  1184.                 flag = 3; break; /* read */
  1185.         case OPLATE :
  1186.         case OCHAIN:
  1187.         case OLEATHER :
  1188.         case ORING :
  1189.         case OSTUDLEATHER :
  1190.         case OSPLINT :
  1191.         case OPLATEARMOR :
  1192.         case OSSPLATE :
  1193.         case OSHIELD :
  1194.         case OELVENCHAIN :
  1195.                 flag = 4; break; /* wear */
  1196.         case OCOOKIE:
  1197.                 flag = 5; break; /* eat */
  1198.         default :    flag = 0; break;
  1199.         }
  1200.         if (!d) switch (flag) {
  1201.         case 0 :    break;
  1202.         case 1 :     if (wld) gack[i++] = j;
  1203.                 break;
  1204.         case 2 :     if (q) gack[i++] = j;
  1205.                 break;
  1206.         case 3 :     if (r) gack[i++] = j;
  1207.                 break;
  1208.         case 4 :     if (w) gack[i++] = j;
  1209.                 break;
  1210.         case 5 :     if (e) gack[i++] = j;
  1211.         default :     break;
  1212.         }
  1213.         else if (iven[j]) gack[i++] = j;
  1214.     }
  1215.     lprintf("\nWhat do you want to %s [", str);
  1216.     if (i) {
  1217.         for (j=0;j<i;j++) 
  1218.             lprintf("%c",gack[j] + 'a');
  1219.         lprintf(" ");
  1220.     }
  1221.     lprintf("* for all] ?");
  1222.     i=0; 
  1223.     while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) 
  1224.         i=getcharacter();
  1225.     if (i=='\33')  
  1226.         lprcat(" aborted");
  1227.     return(i);
  1228. }
  1229.  
  1230.  
  1231.  
  1232. /*
  1233.     subroutine to get a number from the player
  1234.     and allow * to mean return amt, else return the number entered
  1235.  */
  1236. long readnum(mx)
  1237. long mx;
  1238. {
  1239.     register int i;
  1240.     long amt=0;
  1241.  
  1242.     sncbr();
  1243.     if ((i=getcharacter()) == '*')  
  1244.         amt = mx;   /* allow him to say * for all gold */
  1245.     else while (i != '\n') {
  1246.         if (i=='\033') { scbr(); lprcat(" aborted"); return(0); }
  1247.         if ((i <= '9') && (i >= '0') && (amt<999999999))
  1248.             amt = amt*10+i-'0';
  1249.         i = getcharacter();
  1250.     }
  1251.     scbr();  
  1252.     return(amt);
  1253. }
  1254.